//

#include "base.hpp"
#include "testdialog.hpp"
#include "renderengine.hpp"
#include "game.hpp"
#include "gameview.hpp"

using namespace wtk;



static constexpr wgl::WindowSettings WINDOW_SETTINGS
  {
    640,
    480,
    false, // fullscreen
    false, // desktop_fullscreen
    true,  // vsync
  };



// setup_engine
//
static void setup_engine ( RenderEngine &engine )
{
  PipelineID p_wire = engine.register_pipeline
    ({
      "col_unlit.vert",
      "col_unlit.frag",
      GL_LINE, // polygon mode
      false, // textured
      true // depth test
    });

  PipelineID p_col_unlit = engine.register_pipeline
    ({
      "col_unlit.vert",
      "col_unlit.frag",
      GL_FILL, // polygon mode
      false, // textured
      true // depth test
    });

  PipelineID p_tex_lit = engine.register_pipeline
    ({
      "tex_lit.vert",
      "tex_lit.frag",
      GL_FILL, // polygon mode
      true, // textured
      true, // depth test
      true // normal matrix
    });

  /*RenderModeID r_col_unlit = */ engine.register_render_mode
    ({
      {
        {ENTITY_MARKER, p_wire},
        {ENTITY_OBJECT, p_col_unlit},
        {ENTITY_LIGHT_SOURCE, p_col_unlit},
      }
    });

  /*RenderModeID r_tex_lit = */ engine.register_render_mode
    ({
      {
        {ENTITY_MARKER, p_wire},
        {ENTITY_OBJECT, p_tex_lit},
        {ENTITY_LIGHT_SOURCE, p_col_unlit},
      }
    });
}



// setup_sd_layout
//
static void setup_sd_layout ( SDLayout &sd )
{
  sd.register_uniform_block
    ({
      "Matrices",
      {
        { "projection", "mat4" },
        { "model",      "mat4" },
        { "normal",     "mat3" },
      },
    });

  sd.register_struct_type
    ({
      "Light",
      {
        { "pos",       "vec3" },
        { "ambient",   "vec3" },
        { "diffuse",   "vec3" },
        { "specular",  "vec3" },
        { "type",      "int" },
      },
    });

  sd.register_uniform_block
    ({
      "Lighting",
      {
        { "view_pos", "vec3" },
        { "lights", "Light", MAX_LIGHTS },
      },
    });

  sd.register_uniform_block
    ({
      "Material",
      {
        { "ambient", "vec3" },
        { "diffuse", "vec3" },
        { "specular", "vec3" },
        { "shininess", "float" },
      },
    });

  // sd.dump_uniform_block("Lighting");
}



// main
//
int main ( int argc,
           char *argv[] )
{
  Application app{};
  app.enable_application_layers({
      "WGL_LAYER_debug",
    });

  RenderEngine engine{};
  setup_engine(engine);
  setup_sd_layout(engine.get_sd_layout());
  
  Display display{WINDOW_SETTINGS};

  Game game{};
  game.init();
  
  GameView game_view{display, engine, game};
  display.set_top_widget_layout(game_view, true);
  game_view.show_all();
  game_view.set_focus();

  BinLayout dialog_layout{};
  TestDialog dialog{display};
  dialog.set_layout(dialog_layout);  
  Label label{&dialog, "Heljo Worlq!!!"};
  dialog.show_all();

  display.open();

  // main loop
  WM &wm = WM::get();
  auto clock = std::chrono::steady_clock::now(); 
  while (wm.poll_events())
    {
      auto clock2 = std::chrono::steady_clock::now();
      std::chrono::duration<double> dtime = clock2 - clock;
      clock = clock2;
      game.update(dtime.count());
      wm.update();
    }

  return 0;
}
